package com.suray.wcs.service.plc.util;

import com.suray.basic.wcs.path.core.Lifter;
import com.suray.basic.wcs.path.core.Node;
import com.suray.basic.wcs.plc.enums.LifterMode;
import com.suray.basic.wcs.plc.enums.Location;
import com.suray.basic.wcs.plc.pojo.oper.lifter.LifterOper;
import com.suray.wcs.service.execption.PlcExecuteException;
import com.suray.wcs.service.pojo.Rgv;
import com.suray.wcs.service.system.entity.TaskDB;
import com.suray.wcs.service.system.entity.TaskDetailDB;

import java.io.IOException;

/**
 * 提升机调用集合类
 *
 * @author suray
 */
public interface LifterEventInterface {

    /**
     * 车请求提升机第一步
     *
     * @param endLayer 目的层
     * @throws PlcExecuteException
     */
    void rgvNotLoadAssignHoist1(LifterOper hoistOper, Lifter lifter, Rgv rgv, Integer plcId, int endLayer) throws IOException;

    /**
     * 车请求提升机第二步
     *
     * @param hoistOper 提升机对象
     * @param endLayer  目的层
     * @throws PlcExecuteException
     */
    void rgvNotLoadAssignHoist2(LifterOper hoistOper, Lifter lifter, Rgv rgv, Integer plcId, int endLayer) throws IOException;

    /**
     * 货调提升机，使用前，加锁
     *
     * @param lifterOper    提升机操作对象
     * @param lifterNode    提升机所在坐标，不是左右坐标
     * @param taskdb        当前执行的任务
     * @param startLayer    起始层
     * @param endLayer      目的层
     * @param startLocation 起始位置
     * @param endLocation   目的位置
     * @throws PlcExecuteException
     */
    void palletTask(LifterOper lifterOper, Lifter lifterNode, TaskDB taskdb, Node startNode, int startLayer, int endLayer,
                           Location startLocation, Location endLocation, TaskDetailDB taskDetailDB) throws IOException;


    /**
     * 发送小车到位信号
     *
     * @return
     */
    void sendShuttleArrived(LifterOper hoistOper) throws IOException;

    /**
     * 发送小车驶离信号
     *
     * @return
     */
    void sendShuttleLeave(LifterOper hoistOper) throws IOException;

    /**
     * 调用提升机前的安全验证
     *
     * @param hoistOper
     * @param taskNo       发给PLC的编号
     * @param lifterMode   模式
     * @param objFloor1    起始层
     * @param objLocation1 起始位置
     * @param objFloor2    目标层
     * @param objLocation2 目标层
     * @throws PlcExecuteException
     */
    Integer validateAndCall(LifterOper hoistOper, Lifter lifter, Object obj, int taskNo,
                            LifterMode lifterMode, int objFloor1, Location objLocation1, int objFloor2, Location objLocation2) throws IOException;

    /**
     * 提升机到达目标层验证
     *
     * @param hoistOper
     * @param endLayer
     * @throws PlcExecuteException
     */
    void validateHoistArrived(LifterOper hoistOper, int endLayer, int taskNo, Rgv rgv);

    /**
     * 检测当前提升机任务是否完成
     *
     * @param hoistOper
     * @param taskId
     */
    void checkHoistTaskFinish(LifterOper hoistOper, int taskId, int endLayer, TaskDB taskDB);

    /**
     * 提升机故障问题验证，出现该问题时无法通过等待获取资源 此时自动结束当前任务
     *
     * @throws PlcExecuteException
     */
    void errorValidate(LifterOper hoistOper);

    /**
     * 目标层左右是否有货
     *
     * @param endLayer    层 提升机内部的层传1-10任意数字
     * @param endLocation 位置
     * @param lifterOper
     * @return 有货 true
     */
    boolean isPalletExisted(LifterOper lifterOper, Integer endLayer, Location endLocation);
}
